#import "XMAudioRecorder.h"


@interface XMAudioRecorder ()
@property (nonatomic, weak) id<XMAudioRecorderDelegate> delegate;
@property (nonatomic, strong) AVAudioRecorder *avAudioRecorder;
@property (nonatomic, strong) NSMutableDictionary *audioRecorderSetting;
@property (nonatomic, strong) NSTimer *recorderTimer;
@property (nonatomic, copy) NSString *recordFilePath;
@property (nonatomic, assign) double audioRecorderTime;
@end


@implementation XMAudioRecorder
+ (XMAudioRecorder *)shareInstance {
    static XMAudioRecorder *staticAudioRecorder;
    static dispatch_once_t once;
    dispatch_once(&once, ^{
        staticAudioRecorder = [[self alloc] init];
    });
    return staticAudioRecorder;
}
#pragma mark - 初始化
- (instancetype)init {
    self = [super init];
    if (self) {
        [self initAudioRecorderSetting];
    }
    return self;
}
- (void)initAudioRecorderSetting {
    self.audioRecorderSetting = [NSMutableDictionary dictionary];
    [self.audioRecorderSetting setValue:[NSNumber numberWithInt:kAudioFormatMPEG4AAC] forKey:AVFormatIDKey];
    [self.audioRecorderSetting setValue:[NSNumber numberWithInt:8000] forKey:AVSampleRateKey];
    [self.audioRecorderSetting setValue:[NSNumber numberWithInt:1] forKey:AVNumberOfChannelsKey];
    [self.audioRecorderSetting setValue:[NSNumber numberWithInt:16] forKey:AVLinearPCMBitDepthKey];
    [self.audioRecorderSetting setObject:@(YES) forKey:AVLinearPCMIsFloatKey];
    [self.audioRecorderSetting setValue:[NSNumber numberWithInt:AVAudioQualityHigh] forKey:AVEncoderAudioQualityKey];
}
- (void)setRecorderDelegate:(id<XMAudioRecorderDelegate>)recorderDelegate {
    self.delegate = recorderDelegate;
}
- (void)setRecorderSetting:(NSMutableDictionary *)settingDict {
    self.audioRecorderSetting = settingDict;
}
- (NSError *)startRecordWithFilePath:(NSString *)filePath {
    self.recordFilePath = filePath;
    if (self.isRecording) {
        [self stopRecord];
    }
    NSURL *url = [NSURL fileURLWithPath:filePath];
    NSError *error = nil;
    self.avAudioRecorder = [[AVAudioRecorder alloc] initWithURL:url settings:self.audioRecorderSetting error:&error];
    self.avAudioRecorder.meteringEnabled = YES;
    self.avAudioRecorder.delegate = self;
    if (self.avAudioRecorder && (error == nil)) {
        
        AVAudioSession *recoderSession = [AVAudioSession sharedInstance];
        
        [recoderSession setActive:NO error:nil];
        [recoderSession setCategory:AVAudioSessionCategoryPlayAndRecord  withOptions:AVAudioSessionCategoryOptionDefaultToSpeaker error:nil ];
        [recoderSession setActive:YES error:nil];
        
        if ([self.avAudioRecorder prepareToRecord]) {
            self.audioRecorderTime = 0.f;
            [self.avAudioRecorder record];
            [self startTimer];
        }
    }
    return error;
}
- (void)pauseRecord {
    if ([self.avAudioRecorder isRecording]) {
        [self.avAudioRecorder pause];
        self.recorderTimer.fireDate = [NSDate distantFuture];
    }
}
- (void)resumeRecord {
    if (![self.avAudioRecorder isRecording]) {
        [self.avAudioRecorder record];
        self.recorderTimer.fireDate = [NSDate distantPast];
    }
}
- (void)stopRecord {
    if (self.avAudioRecorder) {
//        UInt32 doChangeDefaultRoute = 1;
//           AudioSessionSetProperty(kAudioSessionProperty_OverrideCategoryDefaultToSpeaker,sizeof(doChangeDefaultRoute), &doChangeDefaultRoute);

        if ([self.avAudioRecorder isRecording]) {
            self.audioRecorderTime = [self.avAudioRecorder currentTime];
            [self.avAudioRecorder stop];
        }
        self.avAudioRecorder = nil;
    }
    [self stopTimer];
}
- (NSString *)getRecordFilePath {
    return self.recordFilePath;
}
- (NSTimeInterval)getRecordDurationWithFilePath:(NSString *)filePath {
    if (filePath == nil) {
        return self.audioRecorderTime;
    }
    NSURL *urlFile = [NSURL fileURLWithPath:filePath];
    AVAudioPlayer *audioPlayer = [[AVAudioPlayer alloc] initWithContentsOfURL:urlFile error:nil];
    NSTimeInterval time = audioPlayer.duration;
    audioPlayer = nil;
    return time;
}
- (AVAudioRecorder *)getAVAudioRecorder {
    return self.avAudioRecorder;
}

- (BOOL)isRecording {
    return self.avAudioRecorder.isRecording;
}

#pragma mark - timer
- (void)startTimer {
    [self stopTimer];
    self.recorderTimer = [NSTimer scheduledTimerWithTimeInterval:0.017f target:self selector:@selector(recorderVoiceChange) userInfo:nil repeats:YES];
}
- (void)stopTimer {
    if (self.recorderTimer) {
        [self.recorderTimer invalidate];
    }
    self.recorderTimer = nil;
}
- (void)recorderVoiceChange {
    if (self.avAudioRecorder) {
        [self.avAudioRecorder updateMeters];
        double lowPassResults = pow(10, (0.05 * [self.avAudioRecorder peakPowerForChannel:0]));
//        if (self.delegate && ([self.delegate respondsToSelector:@selector(audioRecorderDidVoiceChanged:value:)])) {
//            [self.delegate audioRecorderDidVoiceChanged:self value:lowPassResults];
//        }
    }
}
#pragma mark - AudioRecorderDelegate
- (void)audioRecorderDidFinishRecording:(AVAudioRecorder *)recorder successfully:(BOOL)flag {
    if (self.isClose) {
        return;
    }
    if (self.delegate && ([self.delegate respondsToSelector:@selector(audioRecorderDidFinished:successfully:)])) {
        [self.delegate audioRecorderDidFinished:self successfully:flag];
    }
}
#pragma mark - dealloc
- (void)dealloc {
    if (self.avAudioRecorder) {
        if ([self.avAudioRecorder isRecording]) {
            [self.avAudioRecorder stop];
        }
        self.avAudioRecorder = nil;
    }
    [self stopTimer];
    if (self.audioRecorderSetting) {
        self.audioRecorderSetting = nil;
    }
}
@end
